/**
 * DataManager的复写以及新增
 */

/**
 * 创建新增data
 */
DataManager._databaseFiles.push({ name: "$dataText", src: "Text.json" });
DataManager._databaseFiles.push({ name: "$dataClassPool", src: "ClassPool.json" });

/**
 * 新游戏,变量开关需要在创建游戏对象后请求，不然会被new覆盖
 */
sun_rmnet.setupNewGame = DataManager.setupNewGame;
DataManager.setupNewGame = function () {
    sun_rmnet.setupNewGame.call(this);
    NetManager.emit("map", "get cloud variables");
}

/**
 * ImageManager的复写以及新增
 */

/**
 * 加载net图片
 * @param {string} filename 
 * @returns {Bitmap} 位图
 */
ImageManager.loadNet = function (filename) {
    return this.loadBitmap("img/net/", filename);
}

/**
 * SceneManager的复写以及新增
 */

/**
 * 使游戏最小化时也持续update
 * @returns {boolean} 固定为true
 */
SceneManager.isGameActive = function () {
    return true;
};

/**
 * Game_Actor的复写以及新增
 */

/**
 * 角色的职业名字
 * @returns {string} 职业的具体名字
 */
Game_Actor.prototype.className = function () {
    return $dataClasses[this._classId].name;
}

/**
 * 设置角色基础参数
 * @param {object} data 从服务端获取的角色基础数据
 */
Game_Actor.prototype.setNetBase = function (data) {
    const { name, level, classId, characterName, characterIndex, faceName, faceIndex, uid } = data;
    this._name = name;
    // this._profile = actor.profile;
    // this._level = level;
    this._characterName = characterName;
    this._characterIndex = characterIndex;
    this._faceName = faceName;
    this._faceIndex = faceIndex;
    this._classId = classId;
    this._exp[this._classId] = 0;
    this._uid = uid;
    // this._battlerName = battlerName;
}

/**
 * 获取角色uid
 * @returns {number} 角色uid
 */
Game_Actor.prototype.uid = function () {
    return this._uid;
}

/**
 * Game_Party的复写以及新增
 */
/**
 * 将原本的队伍成员固定为只有-网游-玩家当前的角色
 * @returns 
 */
Game_Party.prototype.allMembers = function () {
    return [NetManager.actor, ...NetManager.parthers.allMember()];
}

/**
 * 将原本的队长替换成-网游-玩家当前的角色
 * @returns {Game_Actor}
 */
Game_Party.prototype.leader = function () {
    return NetManager.actor;
}





//fps、ping、玩家人数显示
Graphics.FPSCounter.prototype._createElements = function () {
    this._boxDiv = document.createElement("div");
    this._labelDiv = document.createElement("div");
    this._numberDiv = document.createElement("div");
    this._playerNumDiv = document.createElement("div");
    this._boxDiv.id = "fpsCounterBox";
    this._labelDiv.id = "fpsCounterLabel";
    this._numberDiv.id = "fpsCounterNumber";
    this._playerNumDiv.id = "playerNumber";
    this._boxDiv.style.display = "none";
    this._boxDiv.appendChild(this._labelDiv);
    this._boxDiv.appendChild(this._numberDiv);
    this._boxDiv.appendChild(this._playerNumDiv);
    document.body.appendChild(this._boxDiv);
}

Graphics.FPSCounter.prototype._update = function () {
    const count = this._showFps ? this.fps : this.duration;
    this._labelDiv.textContent = `FPS ${this.fps.toFixed(0)}`;
    this._numberDiv.textContent = `ping ${NetManager.ping.toFixed(0)}`;
    this._playerNumDiv.textContent = `在线人数 ${NetManager.playerNum}`;
}


//种子随机数-pve等联机环境下使用种子随机数是结果同步
sun_rmnet.random = Math.random;
Math.random = function () {
    if (NetManager._randomMode === "seed") {
        return NetManager.seedRandom();
    }
    return sun_rmnet.random();
}

//增加net人物刷新计数，用于根据地图内玩家人数动态调整刷新频率
sun_rmnet.gameMapInitialize = Game_Map.prototype.initialize;
Game_Map.prototype.initialize = function () {
    sun_rmnet.gameMapInitialize.call(this);
    this._netRefreshCount = 0;
}

sun_rmnet.gameMapUpdate = Game_Map.prototype.update;
Game_Map.prototype.update = function (sceneActive) {
    sun_rmnet.gameMapUpdate.call(this, sceneActive);
    this.updateAllPlayer();
}

Game_Map.prototype.updateAllPlayer = function () {
    const players = NetManager.players;
    if (this.needRefreshNet()) {
        for (const player of players.values()) {
            player.update();
        }
        this._netRefreshCount = 0;
    }
    this._netRefreshCount++;
}

Game_Map.prototype.needRefreshNet = function () {
    const coefficient = 10;//系数
    const playerNum = NetManager.players.size;
    if (this._netRefreshCount > Math.floor(playerNum / coefficient)) return true;
    else return false;
}

// 地图 X 坐标转换到画布 X 位置
Game_Map.prototype.mapToCanvasX = function (x) {
    const tileWidth = this.tileWidth();
    const originX = this._displayX * tileWidth;
    const canvasX = x * tileWidth - originX;
    return canvasX;
};

// 地图 Y 坐标转换到画布 Y 位置
Game_Map.prototype.mapToCanvasY = function (y) {
    const tileHeight = this.tileHeight();
    const originY = this._displayY * tileHeight;
    const canvasY = y * tileHeight - originY;
    return canvasY;
};



//(覆盖原方法)进入游戏的位置
Game_Player.prototype.setupForNewGame = function () {
    const { mapId, x, y } = NetManager.startingPoint();
    NetManager.transfer(mapId, x, y, 0, 0);
    SceneManager._scene.fadeOutAll();
    SceneManager.goto(Scene_Map);
}

//场所移动后向服务器广播
sun_rmnet.performTransfer = Game_Player.prototype.performTransfer;
Game_Player.prototype.performTransfer = function () {
    sun_rmnet.performTransfer.call(this);
    const newMapId = $gameMap.mapId();
    const x = $gamePlayer.x;
    const y = $gamePlayer.y;
    const data = { newMapId, x, y };
    //广播地图传送事件
    NetManager.emit("map", "transfer", data);
}

sun_rmnet.executeMove = Game_Player.prototype.executeMove;
Game_Player.prototype.executeMove = function (direction) {
    sun_rmnet.executeMove.call(this, direction);
    //移动时如果有玩家选项窗口处于显示状态时隐藏该窗口
    // if (SceneManager._scene?._playerCommandWindow?.visible) {
    //     SceneManager._scene._playerCommandWindow.hide();
    // }
    const data = {
        "mapId": $gameMap.mapId(),
        "x": $gamePlayer._x,
        "y": $gamePlayer._y,
    }
    NetManager.emit("map", "move", data);
}



//(覆盖原方法)场所移动
Game_Interpreter.prototype.command201 = function (params) {
    if ($gameParty.inBattle() || $gameMessage.isBusy()) {
        return false;
    }
    let mapId, x, y;
    if (params[0] === 0) {
        // 直接指定（Direct designation） 
        mapId = params[1];
        x = params[2];
        y = params[3];
    } else {
        // 变量指定（Designation with variables） 
        mapId = $gameVariables.value(params[1]);
        x = $gameVariables.value(params[2]);
        y = $gameVariables.value(params[3]);
    }
    NetManager.transfer(mapId, x, y, params[4], params[5]);
    // $gamePlayer.reserveTransfer(mapId, x, y, params[4], params[5]);
    this.setWaitMode("transfer");
    return true;
}

//云变量、开关
Game_Switches.prototype.setNetValue = function (switchId, value) {
    if (switchId > 0 && switchId < $dataSystem.switches.length) {
        this._data[switchId] = value;
        this.onChange();
        NetManager.emit("map", 'switches change', { "key": switchId, "value": value });
    }
}

Game_Variables.prototype.setNetValue = function (variableId, value) {
    if (variableId > 0 && variableId < $dataSystem.variables.length) {
        if (typeof value === "number") {
            value = Math.floor(value);
        }
        this._data[variableId] = value;
        this.onChange();
        NetManager.emit("map", 'variables change', { "key": variableId, "value": value });
    }
}

Game_SelfSwitches.prototype.setNetValue = function (key, value) {
    if (value) {
        this._data[key] = true;
    } else {
        delete this._data[key];
    }
    this.onChange();
    NetManager.emit("map", 'selfSwitches change', { "key": key, "value": value });
}


sun_rmnet.sceneMenuInitialize = Scene_Menu.prototype.initialize;
Scene_Menu.prototype.initialize = function () {
    sun_rmnet.sceneMenuInitialize.call(this);
    NetManager.emit("map", "change map state", "menu");
}

sun_rmnet.sceneMapInitialize = Scene_Map.prototype.initialize;
Scene_Map.prototype.initialize = function () {
    sun_rmnet.sceneMapInitialize.call(this);
    NetManager.emit("map", "change map state", "map");
}
//战斗奖励将改为服务端控制，故将原函数清空
BattleManager.makeRewards = function () {

}